"""
认证模块数据架构

定义与用户认证相关的数据架构，用于API请求和响应的数据验证。
"""

from typing import Optional
from datetime import datetime
import re

from pydantic import BaseModel, EmailStr, Field, field_validator

from app.modules.auth.config import settings


# Token相关模型 --------------------------------------------------------

class Token(BaseModel):
    """访问令牌响应模型"""
    access_token: str
    token_type: str = "bearer"
    expires_at: datetime


class TokenPayload(BaseModel):
    """令牌载荷模型"""
    sub: Optional[int] = None  # 用户ID
    exp: Optional[datetime] = None  # 过期时间


# 用户相关模型 --------------------------------------------------------

class UserBase(BaseModel):
    """用户基础模型"""
    email: Optional[EmailStr] = None
    full_name: Optional[str] = None
    is_active: Optional[bool] = True


class UserCreate(UserBase):
    """用户创建基础模型"""
    email: EmailStr
    password: str = Field(..., min_length=settings.PASSWORD_MIN_LENGTH, max_length=settings.PASSWORD_MAX_LENGTH)
    
    @field_validator('password')
    def validate_password_strength(cls, v):
        """验证密码强度"""
        if settings.PASSWORD_REQUIRE_UPPERCASE and not re.search(r'[A-Z]', v):
            raise ValueError('密码必须包含至少一个大写字母')
        if settings.PASSWORD_REQUIRE_LOWERCASE and not re.search(r'[a-z]', v):
            raise ValueError('密码必须包含至少一个小写字母')
        if settings.PASSWORD_REQUIRE_DIGIT and not re.search(r'\d', v):
            raise ValueError('密码必须包含至少一个数字')
        if settings.PASSWORD_REQUIRE_SPECIAL and not re.search(r'[!@#$%^&*(),.?":{}|<>]', v):
            raise ValueError('密码必须包含至少一个特殊字符')
        return v


class UserRegister(UserCreate):
    """用户注册请求模型"""
    pass


class UserLogin(BaseModel):
    """用户登录请求模型"""
    email: EmailStr
    password: str


class UserDB(UserBase):
    """数据库用户模型"""
    id: int
    is_superuser: bool
    is_email_verified: bool
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True


class UserProfile(UserDB):
    """用户个人资料响应模型"""
    pass


class UserOut(UserBase):
    """用户输出基础模型"""
    id: int
    is_active: bool
    
    class Config:
        from_attributes = True


class UserUpdate(BaseModel):
    """用户更新请求模型"""
    full_name: Optional[str] = None


# 密码管理相关模型 --------------------------------------------------------

class PasswordBase(BaseModel):
    """密码基础模型"""
    new_password: str = Field(..., min_length=settings.PASSWORD_MIN_LENGTH, max_length=settings.PASSWORD_MAX_LENGTH)
    
    @field_validator('new_password')
    def validate_password_strength(cls, v):
        """验证密码强度"""
        if settings.PASSWORD_REQUIRE_UPPERCASE and not re.search(r'[A-Z]', v):
            raise ValueError('密码必须包含至少一个大写字母')
        if settings.PASSWORD_REQUIRE_LOWERCASE and not re.search(r'[a-z]', v):
            raise ValueError('密码必须包含至少一个小写字母')
        if settings.PASSWORD_REQUIRE_DIGIT and not re.search(r'\d', v):
            raise ValueError('密码必须包含至少一个数字')
        if settings.PASSWORD_REQUIRE_SPECIAL and not re.search(r'[!@#$%^&*(),.?":{}|<>]', v):
            raise ValueError('密码必须包含至少一个特殊字符')
        return v


class PasswordChange(PasswordBase):
    """密码修改请求模型"""
    current_password: str


class PasswordResetRequest(BaseModel):
    """密码重置请求模型"""
    email: EmailStr


class PasswordReset(PasswordBase):
    """密码重置模型"""
    token: str


# Email相关模型 --------------------------------------------------------

class EmailVerify(BaseModel):
    """邮箱验证模型"""
    token: str 